﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;

namespace UniSender
{

    // TODO: Doc
    public static class Utility
    {
        public static IDictionary EnumsMapping = new System.Collections.Specialized.ListDictionary();

        static Utility()
        {
            InitEnumsMapping();
        }

        static void InitEnumsMapping()
        {
            var enums = typeof(Utility).Assembly
                .GetTypes()
                .Where(t => t.IsEnum);
            var nativeEnums = enums.Where(t => t.Namespace.StartsWith("UniSender.Native"));
            enums = enums.Except(nativeEnums);
            foreach (var n in nativeEnums)
            {
                var o = enums.Where(t => t.Name == n.Name).FirstOrDefault();
                if (o != null)
                    EnumsMapping.Add(o, n);
            }
        }

        internal static void Update<TKey, TValue>(this IDictionary<TKey, TValue> target, IDictionary<TKey, TValue> values)
        {
            if (values != null)
                foreach (var item in values)
                    target[item.Key] = item.Value;
        }

        internal static TResult IfNotNull<TSource, TResult>(this TSource source, Func<TSource, TResult> convert)
        {
            return source == null ? default(TResult) : convert(source);
        }


        public static string Stringify(this DateTime time)
        {
            return time.ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss");
        }

        public static string Stringify(this DateTime? time)
        {
            return time == null ? null : time.Value.Stringify();
        }

        public static DateTime ParseTime(string s)
        {
            return DateTime.ParseExact(s, "yyyy-MM-dd HH:mm:ss",
                CultureInfo.CurrentCulture,
                DateTimeStyles.AssumeUniversal);
        }

        public static string Stringify(this Enum value)
        {
            if (value == null)
                return null;
            return Enum.GetName((Type)EnumsMapping[value.GetType()] ?? value.GetType(), value);
        }

        public static T ParseEnum<T>(string value)
        {
            if (value == null)
                return default(T);
            return (T)Enum.Parse((Type)EnumsMapping[typeof(T)] ?? typeof(T), value);
        }
    }
}
